﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using BookLink.Data;
using BookLink.Models;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace BookLink.Pages.Books
{
    public class IndexModel : PageModel
    {
        private readonly BookLink.Data.BookLinkContext _context;
        private readonly IConfiguration Configuration;

        public IndexModel(BookLink.Data.BookLinkContext context, IConfiguration configuration)
        {
            _context = context;
            Configuration = configuration;
        }

        //  public IList<Book> Book { get; set; } = default!;
        public PaginatedList<Book> Book { get; set; } = default!;
        // 出于安全原因，必须选择绑定 GET 请求数据以对模型属性进行分页。 请在将用户输入映射到属性前对其进行验证。 当处理依赖查询字符串或路由值的方案时，选择加入 GET 绑定非常有用。
        [BindProperty(SupportsGet = true)]
        public string? SearchString { get; set; }  // 包含用户在搜索文本框中输入的文本。 SearchString 也有 [BindProperty] 属性。 [BindProperty] 会绑定名称与属性相同的表单值和查询字符串。 在 HTTP GET 请求中进行绑定需要 [BindProperty(SupportsGet = true)]
        public SelectList? Genres { get; set; } // 包含分类列表。 Genres 使用户能够从列表中选择一种分类。 SelectList 需要 using Microsoft.AspNetCore.Mvc.Rendering;
        [BindProperty(SupportsGet = true)]
        public string? BookGenre { get; set; } // 包含用户选择的特定分类

        public async Task OnGetAsync(string bookGenre, string searchString, int? pageIndex)
        {
            var books = from b in _context.Book
                        select b;  //  创建了 LINQ 查询用于选择书籍，此时仅对查询进行了定义，还没有对数据库运行查询

            IQueryable<string> genres = from b in _context.Book
                                        orderby b.Genre
                                        select b.Genre;
            BookGenre = bookGenre;
            SearchString = searchString;
            if (!string.IsNullOrEmpty(SearchString))
            {
                books = books.Where(x => x.IsDeleted == 0).Where(x => x.Title.Contains(SearchString));  // Contains 方法在数据库中运行，而不是在 C# 代码中运行, 在 SQL Server 上，Contains 映射到 SQL LIKE，这是不区分大小写的
            }

            if (!string.IsNullOrEmpty(BookGenre))
            {
                books = books.Where(x => x.IsDeleted == 0).Where(x => x.Genre == BookGenre); // 按分类检索
            }
            var pageSize = Configuration.GetValue("PageSize", 10);
            books = books.OrderByDescending(x => x.ReleaseDate);

            Genres = new SelectList(await genres.Distinct().ToListAsync()); // 分类列表
            Book = await PaginatedList<Book>.CreateAsync(books.AsTracking(), pageIndex ?? 1, pageSize);
        }
    }
}
